#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <muduo/net/TcpConnection.h>
#include <unordered_map>
#include <functional>
#include <mutex>
using namespace std;
using namespace muduo;
using namespace muduo::net;

#include "usermodel.hpp"
#include "offlinemessagemodel.hpp"
#include "friendmodel.hpp"
#include "groupmodel.hpp"
#include "redis.hpp"
#include "json.hpp"
using json = nlohmann::json;

// 处理消息的事件回调方法类型
using MsgHandler = function<void(const TcpConnectionPtr &conn, json &js, Timestamp time)>;

// 用于业务模块
class ChatService
{
public:
    static ChatService* instance(); // 单例类

    void login(const TcpConnectionPtr &conn, json &js, Timestamp time); // 登录
    void reg(const TcpConnectionPtr &conn, json &js, Timestamp time); // 注册
    void oneChat(const TcpConnectionPtr &conn, json &js, Timestamp time); // 一对一聊天
    void addFriend(const TcpConnectionPtr &conn, json &js, Timestamp time); // 添加好友
    void loginout(const TcpConnectionPtr &conn, json &js, Timestamp time); // 注销

    void createGroup(const TcpConnectionPtr &conn, json &js, Timestamp time);
    void addGroup(const TcpConnectionPtr &conn, json &js, Timestamp time);
    void groupChat(const TcpConnectionPtr &conn, json &js, Timestamp time);

    
    // 获取消息对应的处理器
    MsgHandler getHandler(int msgid);
    // 处理客户端异常退出
    void clientCloseException(const TcpConnectionPtr &conn);
    // 处理服务器异常，业务重置方法
    void reset();
    // 从redis消息队列中获取订阅的消息
    void handleRedisSubscribeMessage(int userid, string msg);

private:
    ChatService();

    // 存储消息id和其他对应业务的处理方法
    unordered_map<int, MsgHandler> _msgHandlerMap;

    // 存储在线用户的通信连接  id<->TcpConnection    有线程安全问题
    unordered_map<int, TcpConnectionPtr> _userConnMap;

    // 保证_userConnMap的线程安全
    mutex _connMutex;

    // 数据操作类对象
    UserModel _userModel;
    OfflineMsgModel _offlineMsgModel;
    FriendModel _friendModel;
    GroupModel _groupModel;

    Redis _redis;
};


#endif